#include "usb_bsp.h"
#include "usbd_conf.h"
#include "misc.h"

/**
 * @brief  USB_OTG_BSP_Init
 *         Initilizes BSP configurations
 * @param  None
 * @retval None
 */

void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        EXTI_InitTypeDef EXTI_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE);

        /* Configure SOF ID DM DP Pins */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init (GPIOA, &GPIO_InitStructure);

        GPIO_PinAFConfig (GPIOA, GPIO_PinSource8, GPIO_AF_OTG1_FS);
        GPIO_PinAFConfig (GPIOA, GPIO_PinSource11, GPIO_AF_OTG1_FS);
        GPIO_PinAFConfig (GPIOA, GPIO_PinSource12, GPIO_AF_OTG1_FS);

        /* Configure  VBUS Pin */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init (GPIOA, &GPIO_InitStructure);

        /* Configure ID pin */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_Init (GPIOA, &GPIO_InitStructure);
        GPIO_PinAFConfig (GPIOA, GPIO_PinSource10, GPIO_AF_OTG1_FS);

        RCC_APB2PeriphClockCmd (RCC_APB2Periph_SYSCFG, ENABLE);
        RCC_AHB2PeriphClockCmd (RCC_AHB2Periph_OTG_FS, ENABLE);

        /* enable the PWR clock */
        RCC_APB1PeriphResetCmd (RCC_APB1Periph_PWR, ENABLE);

//  /* Configure the Key button in EXTI mode */
//  STM_EVAL_PBInit(Button_KEY, Mode_EXTI);

#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
        EXTI_ClearITPendingBit(EXTI_Line20);

        EXTI_InitStructure.EXTI_Line = EXTI_Line20;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);

        EXTI_ClearITPendingBit(EXTI_Line20);

        NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_WKUP_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

        EXTI_ClearITPendingBit(EXTI_Line20);
#endif
//  EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE);
}

/**
 * @brief  USB_OTG_BSP_EnableInterrupt
 *         Enabele USB Global interrupt
 * @param  None
 * @retval None
 */
void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev)
{
        NVIC_InitTypeDef NVIC_InitStructure;

        NVIC_PriorityGroupConfig (NVIC_PriorityGroup_1 );
        NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init (&NVIC_InitStructure);

#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
        NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_OUT_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
        NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_IN_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
#endif
}

/**
 * @brief  USB_OTG_BSP_uDelay
 *         This function provides delay time in micro sec
 * @param  usec : Value of delay required in micro sec
 * @retval None
 */
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
        uint32_t count = 0;
        const uint32_t utime = (120 * usec / 7);
        do {
                if (++count > utime) {
                        return;
                }
        } while (1);
//        usleep (usec);
}

/**
 * @brief  USB_OTG_BSP_mDelay
 *          This function provides delay time in milli sec
 * @param  msec : Value of delay required in milli sec
 * @retval None
 */
void USB_OTG_BSP_mDelay (const uint32_t msec)
{
        USB_OTG_BSP_uDelay (msec * 1000);
}


